#include "ReflectSystemImp.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>

__BEGIN_NAMESPACE

/**
 * TypeImp
 */
const char* ValueType::Name() { 
	return m_Name; 
}

int ValueType::Category() { 
	return m_Category; 
}

unsigned int ValueType::Length() { 
	return m_Length; 
}

/**
 * ReferenceTypeImp & PointerTypeImp
 */
const char* ReferenceTypeImp::Name() { 
	return m_Name; 
}

int ReferenceTypeImp::Category() { 
	return m_Category; 
}

unsigned int ReferenceTypeImp::Length() { 
	return m_Length; 
}

Type* ReferenceTypeImp::ReferenceTo() {
	return m_RefType; 
}

const char* PointerTypeImp::Name() { 
	return m_Name; 
}

int PointerTypeImp::Category() { 
	return m_Category; 
}

unsigned int PointerTypeImp::Length() { 
	return m_Length; 
}

Type* PointerTypeImp::PointerTo() { 
	return m_PtrType; 
}


/**
 * EnumImp
 */

const char* EnumInfoImp::Name() { 
	return m_ItemPtr->m_Name; 
}

int EnumInfoImp::Value() { 
	return m_ItemPtr->m_Value; 
}

const char* EnumTypeImp::Name() { 
	return m_Name; 
}

int EnumTypeImp::Category() { 
	return m_Category; 
}

unsigned int EnumTypeImp::Length() { 
	return m_Length; 
}

unsigned int EnumTypeImp::Count() { 
	return m_ItemCount; 
}

EnumInfo* EnumTypeImp::Items(unsigned int iid) 
{ 
	static EnumInfoImp s_enum_info;
	s_enum_info.BindItem(m_Items+iid);
	return &s_enum_info;
}

/**
 * Class & Interface
 */

Type* ParameterInfoImp::ParameterType() { 
	return m_ItemPtr->m_Type; 
}

bool ParameterInfoImp::IsOptional() { 
	return m_ItemPtr->m_IsOptional; 
}

const char* ParameterInfoImp::Name() { 
	return m_ItemPtr->m_Name; 
}

void* ParameterInfoImp::RawDefaultValue() { 
	return m_ItemPtr->m_RawDefaultValue; 
}

/**
 * MethodInfoImp
 */

// ParamterStack interface
unsigned int MethodInfoImp::Count() { return m_ItemPtr->m_Count; }
Type* MethodInfoImp::GetParameterType(unsigned int pid) { return m_ItemPtr->m_Items[pid].m_Type; }
void* MethodInfoImp::GetRawParameter(unsigned int pid) { return m_ItemPtr->m_Items[pid].m_RawValue; }
void MethodInfoImp::Push(void* raw_value) {
	if(m_Pid<m_ItemPtr->m_Count)		
		m_ItemPtr->m_Items[m_Pid++].m_RawValue = raw_value;
}

// MethodInfo interface
bool MethodInfoImp::IsPublic() { 
	return FLAG_ACCESS_PUBLIC==((m_ItemPtr->m_Flags)&METHOD_FLAG_ACCESS_MASK); 
}

bool MethodInfoImp::IsProtected() { 
	return FLAG_ACCESS_PROTECTED==((m_ItemPtr->m_Flags)&METHOD_FLAG_ACCESS_MASK); 
}

bool MethodInfoImp::IsPrivate() { 
	return FLAG_ACCESS_PRIVATE==(((m_ItemPtr->m_Flags)&METHOD_FLAG_ACCESS_MASK)); 
}

bool MethodInfoImp::IsStatic() { 
	return 0!=((m_ItemPtr->m_Flags)&METHOD_FLAG_STATIC_MASK); 
}

bool MethodInfoImp::IsConstructor() {
	return 0!=((m_ItemPtr->m_Flags)&METHOD_FLAG_CONSTRUCTOR_MASK); 
}

bool MethodInfoImp::IsVirtual() { 
	return 0!=((m_ItemPtr->m_Flags)&METHOD_FLAG_VIRTUAL_MASK); 
}

Type* MethodInfoImp::ReturnType() {
	return m_ItemPtr->m_ReturnType; 
}

unsigned int MethodInfoImp::ParameterCount() { 
	return m_ItemPtr->m_Count; 
}

ParameterInfo* MethodInfoImp::Parameters(unsigned int pid) 
{ 
	static ParameterInfoImp s_paramter_info;
	s_paramter_info.BindItem(m_ItemPtr->m_Items+pid);
	return &s_paramter_info;
}

ParameterStack* MethodInfoImp::GetParameterStack() {
	return this; 
}

const char* InterfaceTypeImp::Name() { 
	return m_Name; 
}

int InterfaceTypeImp::Category() { 
	return m_Category; 
}

unsigned int InterfaceTypeImp::Length() { 
	return m_Length; 
}

unsigned int InterfaceTypeImp::BaseCount() {
	return m_BaseCount; 
}

InterfaceType* InterfaceTypeImp::Bases(unsigned int bid) { 
	return m_BaseItems[bid]; 
}

unsigned int InterfaceTypeImp::MethodCount() { 
	return m_MethodCount; 
}

MethodInfo* InterfaceTypeImp::Methods(unsigned int mid) { 
	return m_Methods+mid; 
}

/**
 * FieldInfoImp
 */
bool FieldInfoImp::IsPublic() { 
	return FLAG_ACCESS_PUBLIC==((m_ItemPtr->m_Flags)&FIELD_FLAG_ACCESS_MASK); 
}

bool FieldInfoImp::IsProtected() { 
	return FLAG_ACCESS_PROTECTED==((m_ItemPtr->m_Flags)&FIELD_FLAG_ACCESS_MASK); 
}

bool FieldInfoImp::IsPrivate() { 
	return FLAG_ACCESS_PRIVATE==((m_ItemPtr->m_Flags)&FIELD_FLAG_ACCESS_MASK); 
}

bool FieldInfoImp::IsStatic() { 
	return 0!=((m_ItemPtr->m_Flags)&FIELD_FLAG_STATIC_MASK); 
}

bool FieldInfoImp::CanRead() { 
	return 0!=((m_ItemPtr->m_Flags)&FIELD_FLAG_READ_MASK); 
}

bool FieldInfoImp::CanWrite() { 
	return 0!=((m_ItemPtr->m_Flags)&FIELD_FLAG_WRITE_MASK); 
}

Type* FieldInfoImp::FieldType() { 
	return m_ItemPtr->m_Type; 
}

const char* FieldInfoImp::Name() { 
	return m_ItemPtr->m_Name; 
}

void* FieldInfoImp::RawDefaultValue() { 
	return m_ItemPtr->m_RawDefaultValue; 
}

void FieldInfoImp::SetValue(void* obj, void* val ) {
	memcpy(((char*)obj)+m_ItemPtr->m_Offset, val, FieldType()->Length() );
}

void* FieldInfoImp::GetValue(void* obj) {
	return ((char*)obj)+m_ItemPtr->m_Offset;
}

const char* ClassTypeImp::Name() { 
	return m_Name; 
}

int ClassTypeImp::Category() { 
	return m_Category; 
}

unsigned int ClassTypeImp::Length() { 
	return m_Length; 
}

unsigned int ClassTypeImp::BaseCount() {
	return m_BaseCount; 
}

InterfaceType* ClassTypeImp::Bases(unsigned int bid) { 
	return m_BaseItems[bid]; 
}

unsigned int ClassTypeImp::MethodCount() { 
	return m_MethodCount; 
}

MethodInfo* ClassTypeImp::Methods(unsigned int mid) { 
	return m_Methods+mid; 
}

unsigned int ClassTypeImp::FieldCount() {
	return m_FieldCount; 
}

FieldInfo* ClassTypeImp::Fields(unsigned int fid) { 
	return m_Fields+fid; 
}


/**
 * inner default types
 */
static ValueType s_Void("void", Type::TVOID, 0 );
Type* MTVoid = &s_Void;
static ValueType s_Bool("bool", Type::TBOOL, sizeof(bool) );
Type* MTBool = &s_Bool;
static ValueType s_Sbyte("sbyte", Type::TSBYTE, sizeof(sbyte) );
Type* MTSbyte = &s_Sbyte;
static ValueType s_Byte("byte", Type::TBYTE, sizeof(byte) );
Type* MTByte = &s_Byte;
static ValueType s_Short("short", Type::TSHORT, sizeof(short) );
Type* MTShort = &s_Short;
static ValueType s_Word("word", Type::TWORD, sizeof(word) );
Type* MTWord = &s_Word;
static ValueType s_Long("long", Type::TLONG, sizeof(long) );
Type* MTLong = &s_Long;
static ValueType s_Dword("dword", Type::TDWORD, sizeof(dword) );
Type* MTDword = &s_Dword;
static ValueType s_Hyper("hyper", Type::THYPER, sizeof(hyper) );
Type* MTHyper = &s_Hyper;
static ValueType s_Qword("qword", Type::TQWORD, sizeof(qword) );
Type* MTQword = &s_Qword;
static ValueType s_Char("char", Type::TCHAR, sizeof(char) );
Type* MTChar = &s_Char;
static ValueType s_Wchar("wchar_t", Type::TWCHAR, sizeof(wchar_t) );
Type* MTWchar = &s_Wchar;
static ValueType s_Float("float", Type::TFLOAT, sizeof(float) );
Type* MTFloat = &s_Float;
static ValueType s_Double("double", Type::TDOUBLE, sizeof(double) );
Type* MTDouble = &s_Double;


ClassTypeImp s_Object("Object", 0, 0, sizeof(Object), 0, 0, 0, 0);
ClassType* MTObject = &s_Object;


__END_NAMESPACE

